/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-02-19     xuxl       the first version
 */
#include "periodic.h"
#include <rtthread.h>
#include "ble.h"
#include "ic.h"
#include "fram.h"
#include "can.h"
#include "misc.h"

struct rt_thread PeriodicThread;
char PeriodicThreadStack[PERIODIC_THREAD_STACK_SIZE];
uint32_t Hour5s, Hour;

void HourStore(uint32_t Hr, uint32_t Addr)
{
    uint8_t Buf[5];

    memcpy(Buf, (uint8_t *)&Hr, 4);
    Buf[4] = Buf[0] ^ Buf[1] ^ Buf[2] ^ Buf[3];

    FRAM_WriteBuf(Addr, Buf, 5);
}

void HourStoreClear(void)
{
    FRAM_WriteBuf(HOUR_MAIN_STORE_ADDR, "\x00\x00\x00\x00\x00", 5);
    FRAM_WriteBuf(HOUR_BKUP_STORE_ADDR, "\x00\x00\x00\x00\x00", 5);
}

void HourStoreInit(void)
{
    uint8_t Buf[5];

    FRAM_ReadBuf(Buf, HOUR_MAIN_STORE_ADDR, 5);     //将主存储区的小时计读出。
    if(Buf[4] == (Buf[0] ^ Buf[1] ^ Buf[2] ^ Buf[3]))     //校验主存储区的小时计。
    {
        memcpy((void *)&Hour5s, Buf, 4);
        Hour = Hour5s * 5 / 360;
        return;
    }
    else    //主存储区的小时计校验出错。
    {
        FRAM_ReadBuf(Buf, HOUR_BKUP_STORE_ADDR, 5);     //将备份存储区的小时计读出。
        if(Buf[4] == (Buf[0] ^ Buf[1] ^ Buf[2] ^ Buf[3]))     //校验备份存储区的小时计。
        {
           memcpy((void *)&Hour5s, Buf, 4);
           Hour = Hour5s * 5 / 360;
           FRAM_WriteBuf(HOUR_MAIN_STORE_ADDR, Buf, 5);     //将正确的小时计写回主存储区。
           return;
        }
    }

    //主存储区与备份存储区的小时计均校验出错，把小时计清零。
    HourStoreClear();
    rt_kprintf("Stored hour error, reset to 0!\n");
}

void PeriodicThreadEntry(void *param)
{
    static uint8_t Tmr100ms, Tmr1s, Tmr5s, Flag100ms, Flag1s, Flag5s;
	
    while(1)
    {
        if(++Tmr100ms >= 10)
        {
            Tmr100ms = 0;
            Flag100ms = 1;

            if(++Tmr1s >= 10)
            {
                Tmr1s = 0;
                Flag1s = 1;

                if (++Tmr5s >= 5)
                {
                    Tmr5s = 0;
                    Flag5s = 1;
                }
            }
        }

        if(Flag100ms)
        {
            Flag100ms = 0;

            LedCtrl();

            BuzzerCtrl();
			
			if(BLE_IsConnected() == 0)     //未连接
			{
				if(BleConnTimeout)
				{
					BleConnTimeout = 0;
					BuzzerState = BUZZER_STATE_BLE_NOT_CONNECTED;   //从连接变为未连接
					rt_kprintf("BLE disconnected.\n");
				}
				
				if(ReadCardModeTimeout)
				{
					ReadCardModeTimeout = 0;
					LedState = LED_STATE_STATIC;
					rt_kprintf("Exit reading card mode due to BLE disconnection.\n");
				}
			}
			else    //已连接
			{
				if(BleConnTimeout == 0)
				{
					BuzzerState = BUZZER_STATE_BLE_CONNETED;    //从未连接到已连接
					rt_kprintf("BLE connected.\n");
				}
				BleConnTimeout = BLE_CONN_TIMEOUT_SECONDS;
			}			
        }

        if(Flag1s)
        {
            Flag1s = 0;

            if(BleConnTimeout)  //当持续3分钟未收到APP的报文，认为蓝牙已断开。
            {
                if(--BleConnTimeout == 0)
                {
                    rt_kprintf("BLE connection with APP timeout.\n");
                }
            }

            if(ReadCardModeTimeout)
            {
                if(--ReadCardModeTimeout == 0)
                {
                    LedState = LED_STATE_STATIC;
                    rt_kprintf("Card detection timeout, exit reading card mode.\n");
					if(BleConnTimeout)
					{
						uint16_t n = Protocol_CreateSetReadCardModeAckMsg(BleTxDataBuf, PROTOCOL_SET_CMD_RESULT_SUCC);
						ArrayToHexString(BleTxDataBuf, n, ' ', BleTxDataStrBuf);
						rt_kprintf("Send Ack msg for \"set read card mode\" actively to inform APP the exiting of read card mode:\n-- %s--\n",  BleTxDataStrBuf);
						BLE_Send(BleTxDataBuf, n);
					}
                }
            }

            if(SecondAuthTimeout)
            {
                if(--SecondAuthTimeout == 0)
                {
                    BuzzerState = BUZZER_STATE_AUTH_FAIL;
                    LedState = LED_STATE_AUTH_FAIL;
                    rt_kprintf("Waiting for second auth result from app timeout!\n");
                }
            }
        }

        if(Flag5s == 1)
        {
            Flag5s = 0;

            if(VehState == VEH_STATE_START)
            {
                Hour5s++;
                HourStore(Hour5s, HOUR_MAIN_STORE_ADDR);
                HourStore(Hour5s, HOUR_BKUP_STORE_ADDR);
                Hour = Hour5s * 5 / 360;
            }
        }

        rt_thread_mdelay(10);
    }
}

